home *** CD-ROM | disk | FTP | other *** search
/ Interactive Web Graphics with Shout 3D / Interactive Web Graphics With Shout 3D.iso / pc / Shout3Ddemo / Shout3d_runtime / codebase / custom_nodes / TintedImageTexture.java < prev    next >
Text File  |  2000-09-01  |  5KB  |  124 lines

  1. /**    
  2.     Company:        Eyematic Interfaces
  3.     Project:        Shout3D 2.0 Sample Code
  4.     Class:            TintedImageTexture
  5.     Date:            July 12, 2000
  6.     Description:    A subclass of ImageTexture that tints the pixels of the texture.
  7.     (C) Copyright Eyematic Interfaces, Inc. - 1997-2000 - All rights reserved
  8.  */
  9.  
  10. package custom_nodes;
  11. import shout3d.core.*;
  12. import shout3d.*;
  13. import java.awt.Graphics;
  14.  
  15. /**
  16.  * TintedImageTexture
  17.  * 
  18.  * A subclass of ImageTexture that tints the pixels of the texture.
  19.  * 
  20.  * Demonstrates how to use the API on PixelBasedTexture (from which
  21.  * ImageTexture is derived) to take the pixels from the url and then
  22.  * image process them to create a new texture.
  23.  * 
  24.  * @author Paul Isaacs
  25.  */
  26.  
  27. public class TintedImageTexture extends ImageTexture {
  28.  
  29.     final public FloatArrayField  tintColor    = new FloatArrayField(this, "tintColor", Field.COLOR, null);
  30.     
  31.     /**
  32.      * Constructs a default TintedImageTexture node.
  33.      */
  34.     public TintedImageTexture(){
  35.         // Setting this true specifies that any change in the url field causes the 
  36.         // texture file to be fetched immediately, and in the same thread. When 
  37.         // reading from file, the texture is fetched immediately upon reading the 
  38.         // url field.
  39.         // This insures that once this classes' onFieldChange calls the super class 
  40.         // method of the same name, 
  41.         // there is no chance there there is a texture loading in another thread or
  42.         // waiting to be loaded.
  43.         // Hence, updateCustomPixels() will always take effect properly.
  44.         loadASAP.setValue(true);
  45.         
  46.         tintColor.addFieldObserver(this,null);
  47.     }
  48.     
  49.     public void finalize() throws Throwable {
  50.         tintColor.removeFieldObserver(this);
  51.         super.finalize();
  52.     }
  53.     
  54.     public void onFieldChange(Field theField, Object userData) {
  55.         // First, call the base class.
  56.         super.onFieldChange(theField, userData);
  57.         
  58.         // When these fields change, new pixels are loaded into the node
  59.         // based on the fetched url.  Save them for reference purposes in 
  60.         // generateCustomPixels().
  61.         if (theField == url || theField == hasAlphaTexture || theField == loadASAP ){
  62.             // false means don't copy, just get a reference.
  63.             // These arrays will not be edited by this node.
  64.             urlsRed   = getChannel(RED, false);
  65.             urlsGreen = getChannel(RED, false);
  66.             urlsBlue  = getChannel(RED, false);
  67.         }
  68.         // When these fields change, a new texture must be generated by
  69.         // tinting the texture that was read from the url.
  70.         if (theField == url || theField == hasAlphaTexture || theField == loadASAP ||
  71.             theField == tintColor){
  72.             generateCustomPixels();
  73.         }
  74.     }
  75.     
  76.     byte[][] urlsRed, urlsGreen, urlsBlue;
  77.     byte[][] myRed, myGreen, myBlue;
  78.  
  79.     public void generateCustomPixels(){
  80.         if (tintColor.getValue() == null || tintColor.getValue().length != 3 ||
  81.             urlsRed == null || urlsGreen == null || urlsBlue == null ||
  82.             urlsRed.length == 0 || 
  83.             urlsGreen.length != urlsRed.length || urlsBlue.length != urlsRed.length){
  84.             // Do not tint.  Use the original pixels.
  85.             // The alpha can just be set to a reference to the current alpha.
  86.             setCustomPixels(getWidth(), getHeight(), urlsRed, urlsGreen, urlsBlue, 
  87.                             getChannel(ALPHA, false));
  88.         }
  89.         else {
  90.             // Time to tint.
  91.             
  92.             // Get copies of the texture into myRed, myGreen, myBlue if needed.
  93.             if (myRed == null || 
  94.                 myRed.length != urlsRed.length ||
  95.                 myRed[0].length != urlsRed[0].length){
  96.                     myRed   = getChannel(RED, true);
  97.                     myGreen = getChannel(GREEN, true);
  98.                     myBlue  = getChannel(BLUE, true);
  99.             }
  100.             
  101.             // Tint the pixels based on the original:
  102.             if (urlsRed != null){
  103.                 for (int i = 0; i < urlsRed.length; i++){
  104.                     for (int j = 0; j < urlsRed[0].length; j++){
  105.                         // To read from a byte value (which ranges [-128..128]) into a 
  106.                         // value [0..255], you need to do an & with 0x255, as in:
  107.                         // (urlRed[i][j] & 0x255)
  108.                         // Following this, the number can be multiplied by the tintColor, 
  109.                         // expressed with values in the range [0..1] and cast back to a byte
  110.                         // into myRed.
  111.                         myRed[i][j]   = (byte) (tintColor.getValue()[0] * (urlsRed[i][j] & 0xff));
  112.                         myGreen[i][j] = (byte) (tintColor.getValue()[1] * (urlsGreen[i][j] & 0xff));
  113.                         myBlue[i][j]  = (byte) (tintColor.getValue()[2] * (urlsBlue[i][j] & 0xff));
  114.                     }
  115.                 }
  116.                 // For alpha, use a reference to the existing channel.  The
  117.                 // false argument means reference, not copy.
  118.                 setCustomPixels(getWidth(), getHeight(),
  119.                                 myRed, myGreen, myBlue,
  120.                                 getChannel(ALPHA, false));
  121.             }
  122.         }
  123.     }
  124. }